#include "socket/socket.h"
#include "tcp_socket.h"
#include "singletone.h"
#include "network.h"
#include "connection_listener.h"
#include "multicaster.h"
#include "thread_container.h"
#include "acceptor.h"
#include "event_worker.h"
#include "rs_socket.h"

#include "handler/web_acceptor.h"
#include "handler/web_handler.h"
#include "handler/ic_acceptor.h"

#include <boost/shared_ptr.hpp>

boost::shared_ptr<network::multicaster> create_multicaster()
{
	return boost::shared_ptr<network::multicaster>(new network::multicaster(
		network::singletone<network::message_queue>::instance(), 
		network::singletone<network::event_queue>::instance()));
}

boost::shared_ptr<network::i_socket> get_rs232_con()
{
	return boost::shared_ptr<network::i_socket>(new network::rs_socket(
							"/dev/ttyUSB0"));
}

int main(int argc, char *argv[])
{
	boost::shared_ptr<network::thread_container> con(
		new network::thread_container());

	boost::shared_ptr<network::tcp_socket> tcp(new network::tcp_socket());
	tcp->bind(12345);

	boost::shared_ptr<network::tcp_socket> web(new network::tcp_socket());
	web->bind(12346);
	boost::shared_ptr<network::i_socket> rs232(get_rs232_con());

	boost::shared_ptr<network::message_queue> queue(
		network::singletone<network::message_queue>::instance());
	boost::shared_ptr<network::connection_listener> listener(
		new network::connection_listener(tcp, queue));
	boost::shared_ptr<network::receiver> rs_recv(
		new network::receiver(rs232, queue, network::
			singletone<network::configurator>::instance()->
				get_rs232_parser()));
	boost::shared_ptr<network::connection_listener> listener2(
		new network::connection_listener(web, queue));
	con->add(listener);
	con->add(listener2);
	con->add(rs_recv);

	boost::shared_ptr<network::multicaster> multi(create_multicaster());
	boost::shared_ptr<network::acceptor> accept(
		new network::acceptor(tcp, con, queue, multi));
	boost::shared_ptr<handler::web_acceptor> w_acc(
		new handler::web_acceptor(web, rs232, 
					  con, queue, multi));
	boost::shared_ptr<handler::ic_acceptor> ic_acc(
		new handler::ic_acceptor(rs232, web, multi));
	multi->add_handler(accept);
	multi->add_handler(w_acc);
	multi->add_handler(ic_acc);
	con->add(multi);
	for(int i = 0; i < 5; ++i) {
		con->add(boost::shared_ptr<network::event_worker>(
			new network::event_worker(
				network::singletone<network::event_queue>
					::instance())));
	}
	con->start_threads();
	
	listener->run();
	return 0;
}

